package com.hanlink.dsp.ca.model.settings;

import com.hanlink.dsp.BtDspApplication;
import com.hanlink.dsp.DspSettings;
import com.hanlink.dsp.ca.model.channel.SummingChannel;
import com.hanlink.dsp.model.BaseSettings;
import com.hanlink.dsp.protocols.PwmProtocol;
import com.qztech.bluetooth.BluetoothClientManager;
import com.qztech.utils.YzDebug;

import org.xutils.DbManager;
import org.xutils.db.annotation.Column;
import org.xutils.db.annotation.Table;
import org.xutils.ex.DbException;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zhb on 2017/11/29.
 */
@Table(name = "_summing_settings")
public class SummingSettings extends BaseSettings {

    @Column(name = "_type")
    private int type = 2;//0 bluetooth，1 spdif ，2 high ，3 low

    private boolean isCustom = true;

    @Column(name = "_delay")
    private int delay = 40;

    @Column(name =  "_assign")
    private int assign = 0;

    private int carType = 0;
    private int driverType = 0;

    private final List<SummingChannel> mSummingChannels;
    private int lastChannel = 0; //最后选中的channel 默认是0
    public int getType() {
        return type;
    }

    public void setType(int type) {
        if (this.type == type) {
            return;
        }
        this.type = type;
        writeTypeChangedCmd();

    }

    @Override
    public void resetData() {
        type = 2;
        isCustom = true;
        delay = 40;
        assign = 0;
        lastChannel = 0;
        for (SummingChannel channel : mSummingChannels) {
            channel.resetData();
        }
    }

    public int getAssign() {
        return assign;
    }

    public void setAssign(int assign) {
        this.assign = assign;
    }



    public SummingSettings() {
        isCustom = true;
        mSummingChannels = new ArrayList<>();
    }

    public void getChannels(DbManager db) throws DbException {

        List<SummingChannel> schs = null;
        if (db != null){
            schs = db.selector(SummingChannel.class).where("settings_id", "=", this.id).findAll();
        }
        YzDebug.d("getChannels  SummingChannels:" + (schs == null ?" empty ":(" size:"+ schs.size())));
        if (schs == null || schs.size() == 0) {
            schs = new ArrayList<>();
            SummingChannel sc = null;
            for (int i = 0; i < DspSettings.CHANNEL_LENGTH; i++) {
                sc = new SummingChannel(i, new int[DspSettings.CHANNEL_LENGTH], new int[DspSettings.CHANNEL_LENGTH]);
                sc.setSettingsId(id);
                schs.add(sc);
            }
        }
        setSummingChannels(schs);
    }

    public List<SummingChannel> getSummingChannels() {
        return mSummingChannels;
    }

    public void setSummingChannels(List<SummingChannel> summingChannels) {
        synchronized (mSummingChannels){
            mSummingChannels.clear();
            mSummingChannels.addAll(summingChannels);
        }
        for (SummingChannel channel : mSummingChannels) {
            channel.setSettingsId(this.id);
        }
    }

    public void setLastChannel(int lastChannel) {
        if (this.lastChannel == lastChannel) return;
        this.lastChannel = lastChannel;
        writeChannelChangedCmd(type == 2 ? true : false);
    }

    public void setLastChannel(int lastChannel, boolean isHigh) {
        if (this.lastChannel == lastChannel) return;
        this.lastChannel = lastChannel;
        writeChannelChangedCmd(isHigh);
    }

    public SummingChannel getLastSummingChannel(){
        return mSummingChannels.get(lastChannel);
    }
    public int getLastChannel() {
        return lastChannel;
    }


    public int getDelay() {
        return delay;
    }

    public void setDelay(int delay) {
        this.delay = delay;
    }

    @Override
    public String toString() {
        return "SummingSettings{" +
                "id=" + this.id +
                ",refId=" + this.refId +
                ",type=" + type +
                '}'+super.toString();
    }

    private void writeChannelChangedCmd(boolean isHigh) {
        SummingChannel channel = getSummingChannels().get(lastChannel);
        channel.writeCmd(channel.getCmd(isHigh));
    }

    private void writeTypeChangedCmd() {
        List<SummingChannel> summingChannels = getSummingChannels();
        if (summingChannels == null || summingChannels.size() == 0) return;
        switch (type) {
            case 0:
                BluetoothClientManager.getInstance(BtDspApplication.getInstance()).write(PwmProtocol.PWM_BLUETOOTH_ON);
                break;
            case 1:
                BluetoothClientManager.getInstance(BtDspApplication.getInstance()).write(PwmProtocol.SPDF_ON);
                break;
            case 2: {
                BluetoothClientManager.getInstance(BtDspApplication.getInstance()).write(PwmProtocol.HIGH_ON);
                for (SummingChannel channel : summingChannels) {
                    channel.writeCmd(channel.getCmd(true));
                }
                break;
            }
            case 3: {
                BluetoothClientManager.getInstance(BtDspApplication.getInstance()).write(PwmProtocol.LOW_ON);
                for (SummingChannel channel : summingChannels) {
                    channel.writeCmd(channel.getCmd(false));
                }
                break;
            }
        }
    }

    public void setCarType(int carType) {
        this.carType = carType;
    }

    public int getCarType() {
        return carType;
    }

    public int getDriverType() {
        return driverType;
    }

    public void setDriverType(int driverType) {
        this.driverType = driverType;
    }

    public void setCustom(boolean custom) {
        isCustom = custom;
    }

    public boolean isCustom() {
        return isCustom;
    }

    public byte[] getCmd() {
        switch (type) {
            case 0:
                return PwmProtocol.PWM_BLUETOOTH_ON;
            case 1:
                return PwmProtocol.SPDF_ON;
            case 2: {
                SummingChannel channel = getSummingChannels().get(lastChannel);
                return channel.getCmd(true);
            }
            case 3: {
                SummingChannel channel = getSummingChannels().get(lastChannel);
                return channel.getCmd(false);
            }
            default:
                return PwmProtocol.PWM_BLUETOOTH_ON;
        }
    }


    public SummingSettings copy(){
        final SummingSettings ss = new SummingSettings();
        ss.id = id;
        ss.refId = refId;
        ss.type = type;
        ss.isCustom = isCustom;
        ss.delay = delay;
        ss.assign = assign;
        ss.carType = carType;
        ss.driverType = driverType;
        for (SummingChannel channel : mSummingChannels) {
            ss.mSummingChannels.add(channel.copy());
        }
        ss.lastChannel = lastChannel;

        return ss;
    }

    public void copyIdFromSrc(SummingSettings summingSettings) {
        this.id = summingSettings.id;
        this.refId = summingSettings.refId;
        for (SummingChannel dst : mSummingChannels) {
            for (SummingChannel src : summingSettings.mSummingChannels) {
                if (dst.getChannel() == src.getChannel()){
                    dst.setId(src.getId());
                    dst.setSettingsId(src.getSettingsId());
                }
            }
        }
    }
}
